using System;
using ValidationFramework.Configuration;

namespace ValidationFramework.Specifications
{
    /// <summary>
    /// Performs a length validation.
    /// </summary>
    /// <seealso cref="LengthCollectionRule"/>
	/// <seealso cref="LengthStringRule"/>
#if (!SILVERLIGHT)
    [Serializable]
#endif
    public abstract class LengthInRangeBase : SpecificationBase
    {

        // --- Constructors

        /// <param name="errorMessage">The error message for this rule. Pass a null to use the default value.</param>
        /// <param name="propertyTypeHandle">The <see cref="RuntimeTypeHandle"/> that this <see cref="LengthRule"/> can be applied to. Use <see langword="null"/> to indicate it can be applied to any property type.</param>
        /// <param name="maximum">The maximum length allowed.</param>
        /// <param name="minimum">The minimum length allowed.</param>
        /// <param name="useErrorMessageProvider"><c>true</c> to use <see cref="ConfigurationService.ErrorMessageProvider"/> when determining the error message for this <see cref="Rule"/>; otherwise <c>false</c>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="minimum"/> is less than 0.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="maximum"/> is not greater than or equal to <paramref name="minimum"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="errorMessage"/> is a <see cref="string.Empty"/>.</exception>
        protected LengthInRangeBase(int minimum, int maximum)
        {
            if (minimum < 0)
            {
                throw new ArgumentException("Minimum must be greater than 0.", "minimum");
            }
            if (minimum > maximum)
            {
                throw new ArgumentException("Minimum must be less than or equal to Maximum.", "minimum");
            }
            Minimum = minimum;
            Maximum = maximum;
        }


        // --- Properties

        /// <summary>
        /// Gets the maximum length.
        /// </summary>
        public int Maximum
        {
			get;
			set;
        }

        /// <summary>
        /// Gets or sets the minimum length.
        /// </summary>
        public int Minimum
        {
			get;
			set;
        }


        // --- Methods

		public override bool IsEquivalentTo(ISpecification spec)
		{
			var lengthRule = (LengthInRangeBase)spec;
			return lengthRule.Maximum == Maximum && lengthRule.Minimum == Minimum;
		}
    }
}